import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
from matplotlib.patches import Wedge, Rectangle
from datetime import datetime

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 定义常量 - 保存结果的目录
RESULTS_DIR = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\results"


def load_erp_data():
    """加载ERP订单数据"""
    # 定义可能的文件路径
    possible_paths = [
        r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\data\erp_order_data.xlsx",
        r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\erp_order_data.xlsx"
    ]

    for path in possible_paths:
        if os.path.exists(path):
            try:
                df = pd.read_excel(path)
                # 确保日期格式正确
                if 'order_time' in df.columns:
                    df['order_time'] = pd.to_datetime(df['order_time'])
                print(f"✓ 数据加载成功: {path}")
                return df
            except Exception as e:
                print(f"读取 {path} 失败: {e}")
                continue

    raise FileNotFoundError("未找到erp_order_data.xlsx文件，请确认文件是否存在或路径是否正确")


def create_true_racing_track_chart():
    """创建真正的跑道图：2025年上半年各省份销售分布"""
    # 加载数据
    df = load_erp_data()

    # 按省份汇总销售额
    if 'province' in df.columns and 'product_amount' in df.columns:
        # 按省份分组计算总销售额
        sales_by_province = df.groupby('province')['product_amount'].sum().sort_values(ascending=False)
        # 只保留销售额最高的前6个省份
        sales_by_province = sales_by_province.head(6)

        provinces = sales_by_province.index.tolist()
        amounts = sales_by_province.values.tolist()
        total_sales = sum(amounts)

        # 计算各省份的占比
        percentages = [amount / total_sales for amount in amounts]
    else:
        # 创建模拟数据
        provinces = ['上海市', '陕西省', '四川省', '北京市', '江苏省', '广东省']
        amounts = [62133, 59491, 55394, 53735, 52420, 52246]
        total_sales = sum(amounts)
        percentages = [amount / total_sales for amount in amounts]

    # 创建图形 - 深色背景
    fig = plt.figure(figsize=(14, 9), facecolor='#1A1A2E')
    ax = fig.add_subplot(111, facecolor='#1A1A2E')

    # 定义颜色
    colors = ['#E56A72', '#FFB94F', '#4BB5C2', '#5C1E2B', '#2C3E50', '#8A2D3D']

    # 创建真正的跑道图参数
    base_radius = 1.5  # 基础半径
    track_width = 0.2   # 跑道宽度
    start_angle = 180   # 起始角度（度）
    end_angle = 360     # 结束角度（度）
    num_provinces = len(provinces)

    # 绘制每条跑道
    for i in range(num_provinces):
        # 计算起始和结束角度
        start_ratio = sum(percentages[:i])
        end_ratio = sum(percentages[:i + 1])
        sector_start_angle = start_angle + start_ratio * (end_angle - start_angle)
        sector_end_angle = start_angle + end_ratio * (end_angle - start_angle)

        # 计算当前跑道的内圈和外圈半径
        inner_radius = base_radius + i * track_width
        outer_radius = inner_radius + track_width

        # 创建外圈弧形
        wedge_outer = Wedge(
            center=(0, 0),
            r=outer_radius,
            theta1=sector_start_angle,
            theta2=sector_end_angle,
            width=track_width,
            facecolor=colors[i],
            edgecolor='white',
            linewidth=1.5,
            alpha=0.9
        )
        ax.add_patch(wedge_outer)

        # 添加标签
        # 计算标签位置（弧线中点）
        mid_angle = (sector_start_angle + sector_end_angle) / 2
        radius_text = outer_radius + 0.1  # 文本显示的半径
        x = radius_text * np.cos(np.deg2rad(mid_angle))
        y = radius_text * np.sin(np.deg2rad(mid_angle))

        # 标签位置根据左右侧调整
        ha = 'left' if x >= 0 else 'right'
        label_text = f"{provinces[i]} {int(amounts[i])}"

        # 添加标签
        ax.text(x, y, label_text,
                fontsize=12, fontweight='bold', ha=ha, va='center', color='white',
                bbox=dict(boxstyle='round,pad=0.3', facecolor=colors[i], edgecolor='none', alpha=0.7))

    # 添加起点和终点标记
    # 起点
    start_x = base_radius * np.cos(np.deg2rad(start_angle))
    start_y = base_radius * np.sin(np.deg2rad(start_angle))
    ax.plot(start_x, start_y, 'o', markersize=8, markerfacecolor='white', markeredgecolor='white', markeredgewidth=2)
    ax.text(start_x, start_y - 0.2, '起点', fontsize=12, ha='center', va='top', color='white', fontweight='bold')

    # 终点
    end_x = (base_radius + (num_provinces - 1) * track_width) * np.cos(np.deg2rad(end_angle))
    end_y = (base_radius + (num_provinces - 1) * track_width) * np.sin(np.deg2rad(end_angle))
    ax.plot(end_x, end_y, 'o', markersize=8, markerfacecolor='white', markeredgecolor='white', markeredgewidth=2)
    ax.text(end_x, end_y - 0.2, '终点', fontsize=12, ha='center', va='top', color='white', fontweight='bold')

    # 连接所有跑道的起点和终点
    # 连接起点
    for i in range(num_provinces):
        radius_i = base_radius + i * track_width
        start_x_i = radius_i * np.cos(np.deg2rad(start_angle))
        start_y_i = radius_i * np.sin(np.deg2rad(start_angle))
        if i == 0:
            ax.plot([start_x, start_x_i], [start_y, start_y_i], 'w-', linewidth=1, alpha=0.5)
        else:
            prev_radius = base_radius + (i-1) * track_width
            prev_start_x = prev_radius * np.cos(np.deg2rad(start_angle))
            prev_start_y = prev_radius * np.sin(np.deg2rad(start_angle))
            ax.plot([prev_start_x, start_x_i], [prev_start_y, start_y_i], 'w-', linewidth=1, alpha=0.5)

    # 连接终点
    for i in range(num_provinces):
        radius_i = base_radius + i * track_width
        end_x_i = radius_i * np.cos(np.deg2rad(end_angle))
        end_y_i = radius_i * np.sin(np.deg2rad(end_angle))
        if i == 0:
            ax.plot([end_x, end_x_i], [end_y, end_y_i], 'w-', linewidth=1, alpha=0.5)
        else:
            prev_radius = base_radius + (i-1) * track_width
            prev_end_x = prev_radius * np.cos(np.deg2rad(end_angle))
            prev_end_y = prev_radius * np.sin(np.deg2rad(end_angle))
            ax.plot([prev_end_x, end_x_i], [prev_end_y, end_y_i], 'w-', linewidth=1, alpha=0.5)

    # 设置标题
    title_main = '2025年上半年各省份销售分布'
    # 找出最高销售额省份
    max_idx = np.argmax(amounts)
    max_sales = amounts[max_idx]
    max_province = provinces[max_idx]
    title_sub = f'公司总销售额{int(total_sales)}, {max_province}销售额最高{int(max_sales)}, 占比{max_sales / total_sales:.0%}'

    ax.set_title(f'{title_main}\n{title_sub}',
                 fontsize=20, fontweight='bold', pad=25, color='#FFFFFF')

    # 隐藏坐标轴
    ax.set_xlim(-base_radius - 2, base_radius + 2 + (num_provinces - 1) * track_width)
    ax.set_ylim(-base_radius - 2, base_radius + 2 + (num_provinces - 1) * track_width)
    ax.set_aspect('equal')
    ax.axis('off')

    # 添加数据来源
    latest_date = df['order_time'].max() if 'order_time' in df.columns else datetime.now()
    latest_date_str = latest_date.strftime('%Y-%m-%d')
    source_text = f'*注：数据来源于公司销售系统，统计日期截至{latest_date_str}'
    ax.text(0.5, -base_radius - 1.5, source_text, transform=ax.transAxes,
            fontsize=10, color='#B0B0B0', alpha=0.7, va='bottom')

    # 调整布局
    plt.tight_layout()

    # 确保结果目录存在
    os.makedirs(RESULTS_DIR, exist_ok=True)
    # 保存图片
    output_path = os.path.join(RESULTS_DIR, '18_真正跑道图.png')
    plt.savefig(output_path, dpi=300, bbox_inches='tight',
                facecolor='#1A1A2E', edgecolor='none')

    plt.show()

    # 数据分析
    print("真正跑道图数据分析：")
    print(f"- 数据覆盖省份：{len(provinces)}个")
    print(f"- 销售额最高省份：{max_province}，销售额{int(max_sales)}")
    print(f"- 销售额最低省份：{provinces[-1]}，销售额{int(amounts[-1])}")
    print(f"- 总销售额：{int(total_sales)}")

    return fig, ax


# 执行代码
if __name__ == "__main__":
    try:
        fig, ax = create_true_racing_track_chart()
    except Exception as e:
        print(f"图表生成失败: {e}")
        raise
